/*
*  This file is part of ygg-brute
*  Copyright (c) 2020 ygg-brute authors
*  See LICENSE for licensing information
*/

#pragma once

#include <cstring>
#include <cstdio>
#include <stdexcept>
#include <sodium.h>

#include "address.hpp"
#include "generator.hpp"

#define DECLSPEC

#include "generic/node_id.h"

inline void run_generator_test(Generator& gen, GeneratorCtx& ctx, bool ensure_uniqueness = false)
{
    char str[64]{0};

    gen.produce(ctx);
    for(auto i = 0; i < ctx.batch_size(); ++i) {
        if(i % 10000 == 0) printf("generator test: %d\n", i);
        uint8_t skey[32], pkey[32], node_id[64], ipv6[16];
        memcpy(skey, ctx.skey(i), 32);
        crypto_scalarmult_curve25519_base(pkey, skey);
        crypto_hash_sha512(node_id, pkey, 32);
        node_id_to_ipv6(node_id, ipv6);
        auto* gpu_ipv6 = ctx.address(i);
        if(memcmp(ipv6, gpu_ipv6, 16)) {
            ipv6_to_string(ipv6, str);
            printf("computed address: %s\n", str);
            ipv6_to_string(gpu_ipv6, str);
            printf("gpu address: %s\n", str);
            throw std::runtime_error{"generator test failed at " + std::to_string(i)};
        }
    }
}